home *** CD-ROM | disk | FTP | other *** search
/ Windows Expert / Windows Expert.iso / windownt / mdipad.zip / MDIPAD.C < prev    next >
C/C++ Source or Header  |  1993-02-24  |  29KB  |  862 lines

  1. // ************************************************************************
  2. //
  3. //                      Microsoft Developer Support
  4. //               Copyright (c) 1992, 1993 Microsoft Corporation
  5. //
  6. // **************************************************************************
  7. // MODULE    : MdiPad.C
  8. // PURPOSE   : A Small Win16/Win32 MdiPad Application Template
  9. // FUNCTIONS :
  10. //   WinMain()       - initializes the main window, dispatches messages
  11. //   MainWndProc()   - processes messages
  12. //   AboutDlgProc()  - processes messages for "About" dialog box
  13. //   ErrorBox()      - displays and error box when called
  14. // **************************************************************************
  15. #ifndef WIN32S
  16.  #define   UNICODE             // make the application unicode complient
  17. #endif
  18. #define   STRICT               // strict type checking enabled
  19. #include <Windows.H>           // required for all Windows applications
  20. #include <Time.H>
  21.  
  22. #include "Port.H"              // macros for 16/32 bit application creation
  23. #include "MdiPad.H"            // specific to this program
  24. #include "ToolBar.H"
  25.  
  26. #ifdef DEBUG
  27.   #define DebugOut( str ) OutputDebugString (__FILE__ ": " str "\n")
  28. #else
  29.   #define DebugOut( str )
  30. #endif
  31.  
  32. //-- global data
  33. HWND      hWndMain;            // Main window handle
  34. HWND      hWndMdiClient;       // MDI client windows handle
  35. HINSTANCE hInstance;           // current instance
  36. TCHAR     szAppName[32];       // name of the application
  37. TCHAR     szShortAppName[16];  // short name of the application
  38. UINT      cMdiChild = 0;       // Count of number of MDI children created
  39.  
  40. LPCTSTR lpszMdiChildClassName = (LPCTSTR) "MdiChildClass";
  41.  
  42. HWND hWndMenuField, hWndTimeField, hWndOvrField, hWndBogusField, hWndCapsField, hWndNumField;
  43. HWND hWndLabel1,  hWndCombo1,  hWndCombo2;
  44. HWND hWndButton1, hWndButton2, hWndButton3, hWndButton4;
  45. HWND hWndButton5, hWndButton6, hWndButton7;
  46.  
  47. HMENU   hSysMenuMain = (HMENU) NULL;
  48. HMENU   hFileMenu    = (HMENU) NULL;
  49. HMENU   hHelpMenu    = (HMENU) NULL;
  50. HMENU   hSysMenuAdv  = (HMENU) NULL;
  51. HMENU   hMenu        = (HMENU) NULL;
  52.  
  53. //-- internal function prototypes
  54. LRESULT CALLBACK MainWndProc     ( HWND, UINT, WPARAM, LPARAM );
  55. LRESULT CALLBACK MdiChildWndProc ( HWND, UINT, WPARAM, LPARAM );
  56. LRESULT CALLBACK AboutDlgProc    ( HWND, UINT, WPARAM, LPARAM );
  57. BOOL             ErrorMessageBox ( LPCTSTR, LPCTSTR, LPCTSTR, INT );
  58. HWND    WINAPI   CreateMdiChildWindow( LPCTSTR );
  59. VOID    WINAPI   CloseAllMdiChildren( VOID );
  60. BOOL    WINAPI   QueryCloseMdiChild( HWND );
  61.  
  62. BOOL FillFontNameComboBox( HWND, int );
  63. BOOL FillFontSizeComboBox( HWND, int );
  64.  
  65. // **************************************************************************
  66. // FUNCTION : WinMain( HINSTANCE, HINSTANCE, LPSTR, int )
  67. // PURPOSE  : Calls initialization function, processes message loop
  68. // COMMENTS :
  69. // **************************************************************************
  70. int PASCAL
  71. WinMain( HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine, int nCmdShow )
  72. {
  73.   MSG     msg;
  74.   HACCEL  hAccel;
  75.   LPCTSTR lpszClassName = TEXT( "MdiPadClass" );
  76.   LPCTSTR lpszMenuName  = TEXT( "MdiPadMenu"  );
  77.   LPCTSTR lpszIconName  = TEXT( "MdiPadIcon"  );
  78.   LPCTSTR lpszAccelName = TEXT( "MdiPadAccel" );
  79.  
  80.   LPCTSTR lpszMdiChildIconName  = TEXT( "MdiChildIcon" );
  81.  
  82.   UNREFERENCED_PARAMETER( lpCmdLine );  // avoid the warning
  83.  
  84.   hInstance = hInst;
  85.  
  86.   //-- Other instances of app running? If not...
  87.   if( !hPrevInst ) {
  88.     WNDCLASS wndclass;
  89.  
  90.     // Register the frame class
  91.     wndclass.style         = CS_VREDRAW;
  92.     wndclass.lpfnWndProc   = (WNDPROC) MainWndProc;
  93.     wndclass.cbClsExtra    = 0;
  94.     wndclass.cbWndExtra    = 0;
  95.     wndclass.hInstance     = hInstance;
  96.     wndclass.hIcon         = LoadIcon( hInstance, lpszIconName );
  97.     wndclass.hCursor       = LoadCursor( NULL, IDC_ARROW );
  98.     wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
  99.     wndclass.lpszMenuName  = lpszMenuName;
  100.     wndclass.lpszClassName = lpszClassName;
  101.  
  102.     if( !RegisterClass(&wndclass) ) {
  103.       ErrorMessageBox( TEXT("Failed!"), TEXT("RegisterClass()"), (LPCTSTR) __FILE__, __LINE__ );
  104.       return( FALSE );
  105.     }
  106.  
  107.     // Register the MDI child class
  108.     wndclass.style         = 0;
  109.     wndclass.lpfnWndProc   = (WNDPROC) MdiChildWndProc;
  110.     wndclass.cbClsExtra    = 0;
  111.     wndclass.cbWndExtra    = 0;
  112.     wndclass.hInstance     = hInstance;
  113.     wndclass.hIcon         = LoadIcon( hInstance, lpszMdiChildIconName );
  114.     wndclass.hCursor       = LoadCursor( NULL, IDC_IBEAM );
  115.     wndclass.hbrBackground = (HBRUSH) (COLOR_APPWORKSPACE+1);
  116.     wndclass.lpszMenuName  = (LPCTSTR) NULL;
  117.     wndclass.lpszClassName = lpszMdiChildClassName;
  118.  
  119.     if( !RegisterClass(&wndclass) ) {
  120.       ErrorMessageBox( TEXT("Failed!"), TEXT("RegisterClass()"), (LPCTSTR) __FILE__, __LINE__ );
  121.       return( FALSE );
  122.     }
  123.   }
  124.  
  125.   //-- Load resource strings
  126.   if( !LoadString( hInstance, IDS_APPNAME,  szAppName, sizeof(szAppName) ) )
  127.     ErrorMessageBox( TEXT("Failed!"), TEXT("LoadString()"), (LPCTSTR) __FILE__, __LINE__ );
  128.   if( !LoadString( hInstance, IDS_SHORT_APPNAME, szShortAppName,
  129.          sizeof(szShortAppName) ) )
  130.     ErrorMessageBox( TEXT("Failed!"), TEXT("LoadString()"), (LPCTSTR) __FILE__, __LINE__ );
  131.  
  132.   //-- initialize the tool bar
  133.   if( !InitToolBar(hInst) ) {
  134.     DebugOut( "InitToolBar Failed" );
  135.     return FALSE;
  136.   }
  137.  
  138.   //-- initialize the statis bar
  139.   if( !InitStatusBar(hInst) ) {
  140.     DebugOut( "InitStatusBar Failed" );
  141.     return FALSE;
  142.   }
  143.  
  144.   //-- Create the main window
  145.   hWndMain = CreateWindow(
  146.                lpszClassName,        // See RegisterClass() call
  147.                szAppName,            // Text for window title bar
  148.                WS_OVERLAPPEDWINDOW | WS_CLIPCHILDREN,  // Window style
  149.                CW_USEDEFAULT,        // Default horizontal position
  150.                CW_USEDEFAULT,        // Default vertical position
  151.                CW_USEDEFAULT,        // Default width
  152.                CW_USEDEFAULT,        // Default height
  153.                NULL,                 // Overlapped windows have no parent
  154.                NULL,                 // Use the window class menu
  155.                hInstance,            // This instance owns this window
  156.                NULL );               // Pointer not needed
  157.  
  158.   //-- If window could not be created, return "failure"
  159.   if( !hWndMain ) {
  160.     ErrorMessageBox( TEXT("Failed!"), TEXT("CreateWindow()"), (LPCTSTR) __FILE__, __LINE__ );
  161.     return( FALSE );
  162.   }
  163.  
  164.  
  165.  
  166.  
  167.   //-- Get handles to the various menus. Some of these we will use later
  168.   //   to display menu descriptions in the status bar
  169.   hSysMenuMain = GetSystemMenu( hWndMain, FALSE );
  170.   if( !hSysMenuMain )
  171.     DebugOut( "No System Menu" );
  172.     hMenu = GetMenu( hWndMain );
  173.   if( hMenu ) {
  174.     hFileMenu = GetSubMenu( hMenu, 0 );
  175.     hHelpMenu = GetSubMenu( hMenu, 1 );
  176.   }
  177.   else {
  178.     DebugOut( "No Menu Bar" );
  179.   }
  180.  
  181.   //-- Create the ToolBar
  182.   DebugOut( "Call CreateToolBar" );
  183.   if( CreateToolBar( hWndMain, hInstance, ID_TOOLBAR ) ) {
  184.     DebugOut( "CreateToolBar Succeeded" );
  185.     hWndLabel1 = AddToolLabel( hInstance, 0, TEXT( "Font:" ), 0, SS_RIGHT );
  186.     AddToolSpace (6, 0);
  187.     hWndCombo1 = AddToolCombo( hInstance, ID_COMBO1, -25, CBS_DROPDOWN | WS_VSCROLL );
  188.     FillFontNameComboBox( hWndCombo1, 0 );
  189.     AddToolSpace (10, 0);
  190.     hWndCombo2 = AddToolCombo( hInstance, ID_COMBO2, -10, CBS_DROPDOWN | WS_VSCROLL );
  191.     FillFontSizeComboBox( hWndCombo2, 0 );
  192.     AddToolSpace (25, 0);
  193.     hWndButton1 = AddToolButton( hInstance, ID_BOLD, TEXT( "Bold" ), 26, 0, BS_OWNERDRAW );
  194.     AddToolSpace (-1, 0);
  195.     hWndButton2 = AddToolButton( hInstance, ID_ITALIC, TEXT( "Italic" ), 26, 0, BS_OWNERDRAW );
  196.     AddToolSpace (-1, 0);
  197.     hWndButton3 = AddToolButton( hInstance, ID_UNDER, TEXT( "Under" ), 26, 0, BS_OWNERDRAW );
  198.     AddToolSpace (10, 0);
  199.     hWndButton4 = AddToolButton( hInstance, ID_LEFT,  TEXT( "Left" ),    26, 0, BS_OWNERDRAW );
  200.     AddToolSpace (-1, 0);
  201.     hWndButton5 = AddToolButton( hInstance, ID_CENTER, TEXT( "Center" ),  26, 0, BS_OWNERDRAW );
  202.     AddToolSpace (-1, 0);
  203.     hWndButton6 = AddToolButton( hInstance, ID_RIGHT, TEXT( "Right" ),   26, 0, BS_OWNERDRAW );
  204.     AddToolSpace (-1, 0);
  205.     hWndButton7 = AddToolButton( hInstance, ID_JUST,  TEXT( "Just" ),    26, 0, BS_OWNERDRAW );
  206.     AddToolSpace (-1, 0);
  207.   }
  208.   else {
  209.     DebugOut( "CreateToolBar Failed" );
  210.     return FALSE;
  211.   }
  212.  
  213.   //-- Create the StatusBar
  214.   DebugOut( "Call CreateStatusBar" );
  215.   if( CreateStatusBar(hWndMain, hInstance, ID_STATUSBAR) ) {
  216.     DebugOut( "CreateStatusBar Succeeded" );
  217.     hWndMenuField = AddStatusField( hInstance, ID_MENUFIELD, 100, 0, FALSE);
  218.     hWndTimeField = AddStatusField( hInstance, ID_TIMEFIELD, -12, -12, TRUE);
  219.     if( hWndTimeField ) {
  220.       SetTimer( hWndMain, 1, 1000, NULL );
  221.     }
  222.     hWndOvrField   = AddStatusField( hInstance, ID_OVRFIELD,    -6, -6, TRUE  );
  223.     hWndBogusField = AddStatusField( hInstance, ID_SCROLLFIELD, -6, -6, FALSE );
  224.     hWndCapsField  = AddStatusField( hInstance, ID_CAPSFIELD,   -6, -6, FALSE );
  225.     hWndNumField   = AddStatusField( hInstance, ID_NUMFIELD,    -6, -6, FALSE );
  226.   }
  227.   else {
  228.     DebugOut( "CreateStatusBar Failed" );
  229.     return FALSE;
  230.   }
  231.  
  232.   //-- Load main menu accelerators
  233.   if( !(hAccel = LoadAccelerators( hInstance, lpszAccelName) ) ) {
  234.     ErrorMessageBox( TEXT("Failed!"), TEXT("LoadAccelerators()"), (LPCTSTR) __FILE__, __LINE__ );
  235.     return( FALSE );
  236.   }
  237.  
  238.   //-- Create an MDI clint window
  239.   {
  240.     CLIENTCREATESTRUCT ccs;
  241.  
  242.     // Find window menu where children will be listed
  243.     ccs.hWindowMenu = GetSubMenu( GetMenu(hWndMain), WINDOWMENU );
  244.     ccs.idFirstChild = IDM_FIRSTCHILD;
  245.  
  246.     hWndMdiClient = CreateWindow(
  247.                       TEXT( "MdiClient" ),
  248.                        NULL,
  249.                        WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS |
  250.                        WS_HSCROLL | WS_VSCROLL,
  251.                        0, 0, 0, 0,
  252.                        hWndMain,
  253.                        (HMENU) NULL,
  254.                        hInstance,
  255.                        (LPSTR) &ccs );
  256.  
  257.   }
  258.   //-- If window could not be created, return "failure"
  259.   if( !hWndMdiClient ) {
  260.     ErrorMessageBox( TEXT("Failed!"), TEXT("CreateWindow()"), (LPCTSTR) __FILE__, __LINE__ );
  261.     return( FALSE );
  262.   }
  263.  
  264.   ShowWindow( hWndMdiClient, SW_SHOW );
  265.   //-- Make the window visible; update its client area; and return "success"
  266.   ShowWindow( hWndMain, nCmdShow );  // Show the window
  267.   UpdateWindow( hWndMain );          // Sends WM_PAINT message
  268.  
  269.   //-- Acquire and dispatch messages until a WM_QUIT message is received.
  270.   while( GetMessage( &msg, NULL, 0, 0 ) ) {
  271.     if( !TranslateMDISysAccel( hWndMdiClient, &msg ) ) {
  272.       if( !TranslateAccelerator( hWndMain, hAccel, &msg ) ) {
  273.         TranslateMessage( &msg );     // Translates virtual key codes
  274.         DispatchMessage( &msg );      // Dispatches message to window
  275.       }
  276.     }
  277.   }
  278.  
  279.   return( msg.wParam );           // Returns the value from PostQuitMessage
  280. }
  281.  
  282.  
  283. // **************************************************************************
  284. // FUNCTION : MainWndProc( HWND, UINT, WPARAM, LPARAM )
  285. // PURPOSE  : Processes messages
  286. // MESSAGES :
  287. //   WM_COMMAND         - application menu
  288. //     IDM_FILE_EXIT    - exit the application
  289. //     IDM_HELP_ABOUT   - About Dialog Box
  290. //     ...
  291. //   WM_CREATE          - window initialization
  292. //   WM_SIZE            - saves window width and height when resized
  293. //   WM_CLOSE           - handles cleanup
  294. //   WM_DESTROY         - destroys window
  295. // **************************************************************************
  296. LRESULT CALLBACK
  297. MainWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  298. {
  299.   static  INT        idMenuSelect;
  300.  
  301.   time_t  lTime;
  302.   struct tm *datetime;
  303.  
  304.   #define HOUR (datetime->tm_hour)
  305.   #define MIN (datetime->tm_min)
  306.   #define SEC (datetime->tm_sec)
  307.  
  308.   TCHAR   szTime[20];
  309.   INT     tmp;
  310.   INT     wmMenuCmd, wmFlags;
  311.   HMENU   wmhMenu;
  312.   TCHAR   szMsg[80] = TEXT( "" );
  313.  
  314.   switch( uMsg ) {
  315.  
  316.     case WM_COMMAND: {    // message: command from application menu
  317.  
  318.       switch( LOWORD( wParam ) ) {
  319.  
  320.         case IDM_FILE_NEW: {
  321.           // Create a new MDI child window
  322.           TCHAR MdiChildName[64];
  323.  
  324.           wsprintf( MdiChildName, TEXT( "MDI Child #%d" ), ++cMdiChild );
  325.           CreateMdiChildWindow( MdiChildName );
  326.           return( FALSE );
  327.         }
  328.  
  329.         case IDM_FILE_OPEN:
  330.           MessageBeep( (UINT) -1 );
  331.           return( FALSE );
  332.  
  333.         case IDM_FILE_EXIT:
  334.           SendMessage( hWnd, WM_CLOSE, 0, 0 );
  335.           return( FALSE );
  336.  
  337.         case IDM_WINDOW_CASCADE:
  338.           // Cascade MDI windows
  339.           SendMessage( hWndMdiClient, WM_MDICASCADE, 0, 0L );
  340.           return( FALSE );
  341.  
  342.         case IDM_WINDOW_TILE_HORZ:
  343.           // Tile MDI windows
  344.           SendMessage( hWndMdiClient, WM_MDITILE, MDITILE_HORIZONTAL, 0L );
  345.           return( FALSE );
  346.  
  347.         case IDM_WINDOW_TILE_VERT:
  348.           // Tile MDI windows
  349.           SendMessage( hWndMdiClient, WM_MDITILE, MDITILE_VERTICAL, 0L );
  350.           return( FALSE );
  351.  
  352.         case IDM_WINDOW_ARRANGEICONS:
  353.           // Auto - arrange MDI icons
  354.           SendMessage( hWndMdiClient, WM_MDIICONARRANGE, 0, 0L );
  355.           return( FALSE );
  356.  
  357.         case IDM_WINDOW_CLOSEALL:
  358.           CloseAllMdiChildren();
  359.           cMdiChild = 0;
  360.           return( FALSE );
  361.  
  362.         case IDM_HELP_ABOUT: {
  363.           DLGPROC lpfnAboutDlgProc;  // pointer to the "About" function
  364.           LPTSTR  lpszAboutSample = TEXT("AboutDlgBox");
  365.  
  366.           lpfnAboutDlgProc = (DLGPROC) MakeProcInstance( (FARPROC) AboutDlgProc, hInstance );
  367.           if( DialogBox( hInstance, lpszAboutSample, hWnd, lpfnAboutDlgProc ) == -1)
  368.             ErrorMessageBox( TEXT("Failed!"), TEXT("DialogBox()"), (LPCTSTR) __FILE__, __LINE__ );
  369.           FreeProcInstance( (FARPROC) lpfnAboutDlgProc );
  370.           return( FALSE );
  371.         }
  372.  
  373.         default:
  374.           // This is essential, since there are frame WM_COMMANDS generated
  375.           // by the MDI system for activating child windows via the
  376.           // window menu.
  377.           return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
  378.       }
  379.     }
  380.  
  381.     case WM_WINDOWPOSCHANGING: {
  382.      LPWINDOWPOS lpWinPos = (LPWINDOWPOS) lParam;
  383.  
  384.      lpWinPos->x = 64;
  385.      lpWinPos->y = 64;
  386.      return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
  387.     }
  388.  
  389.     //-- handle the WM_SIZE message ourselves so we can resize the
  390.     //    the MDI client windows to exclude the toolbar and the
  391.     //    status bar
  392.     case WM_SIZE: {
  393.       RECT rect;
  394.  
  395.       AdjustToolBar( hWnd );
  396.       AdjustStatusBar( hWnd );
  397.       GetClientRect (hWnd, &rect);
  398.       SetWindowPos( hWndMdiClient, NULL,
  399.         0, (ToolBarHeight( hWnd )+1),
  400.         rect.right - rect.left, rect.bottom
  401.         - (ToolBarHeight( NULL )+1) - (StatusBarHeight( NULL )+1),
  402.         SWP_SHOWWINDOW );
  403.  
  404.       return( FALSE );
  405.       // return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
  406.     }
  407.  
  408.     case WM_TIMER:
  409.   #ifndef WIN32
  410.       SetWindowText (hWndTimeField, TEXT("No Time") );
  411.   #else
  412.       time (&lTime);
  413.       datetime = localtime (&lTime);
  414.       wsprintf(
  415.         szTime,
  416.         TEXT( "%02d:%02d:%02d %s" ),
  417.         (HOUR%12?HOUR%12:12), MIN, SEC,
  418.         (LPTSTR) ( HOUR/12  ? TEXT("PM"):TEXT("AM") ) );
  419.       SetWindowText (hWndTimeField, szTime);
  420.   #endif
  421.       if (GetKeyState (VK_NUMLOCK)&1)
  422.         SetWindowText (hWndNumField, TEXT( "NUM" ) );
  423.       else
  424.         SetWindowText (hWndNumField, TEXT( "" ) );
  425.  
  426.       if (GetKeyState (VK_CAPITAL)&1)
  427.         SetWindowText (hWndCapsField, TEXT( "CAPS" ) );
  428.       else
  429.         SetWindowText (hWndCapsField, TEXT( "" ) );
  430.  
  431.       if (GetKeyState (VK_INSERT)&1)
  432.         SetWindowText (hWndOvrField, TEXT( "OVR" ) );
  433.       else
  434.         SetWindowText (hWndOvrField, TEXT( "" ) );
  435.  
  436.       break;
  437.  
  438.     case WM_KEYUP:
  439.     case WM_KEYDOWN:
  440.       if (GetKeyState (VK_NUMLOCK)&1)
  441.         SetWindowText (hWndNumField, TEXT( "NUM" ) );
  442.       else
  443.         SetWindowText (hWndNumField, TEXT( "" ) );
  444.  
  445.       if (GetKeyState (VK_CAPITAL)&1)
  446.         SetWindowText (hWndCapsField, TEXT( "CAPS" ) );
  447.       else
  448.         SetWindowText (hWndCapsField, TEXT( "" ) );
  449.  
  450.       if (GetKeyState (VK_INSERT)&1)
  451.         SetWindowText (hWndOvrField, TEXT( "OVR" ) );
  452.       else
  453.         SetWindowText (hWndOvrField, TEXT( "" ) );
  454.  
  455.       #define VK_OEM_SCROLL 0x91 // This isn't in WINDOWS.H, will it always work?
  456.  
  457.       if (GetKeyState (VK_OEM_SCROLL)&1)
  458.         SetWindowText (hWndBogusField, TEXT( "SCROLL" ) );
  459.       else
  460.         SetWindowText (hWndBogusField, TEXT( "" ) );
  461.  
  462.       return DefWindowProc (hWnd, uMsg, wParam, lParam);
  463.       break;
  464.  
  465.     case WM_CHAR:
  466.       switch (wParam) {
  467.         case VK_F10:
  468.           wParam = VK_MENU;
  469.           return DefWindowProc (hWnd, uMsg, wParam, lParam);
  470.           break;
  471.       }
  472.       break;
  473.  
  474.     case WM_MENUSELECT:
  475.       /* A menu item is hilited, get description text for status bar */
  476.       tmp = idMenuSelect;
  477.  
  478.      #if defined (WIN32)
  479.       wmMenuCmd = LOWORD( wParam );
  480.       wmFlags   = HIWORD( wParam );
  481.       wmhMenu   = (HMENU) lParam;
  482.      #elif defined (WIN16)
  483.       wmMenuCmd = wParam;
  484.       wmFlags   = LOWORD( lParam );
  485.       wmhMenu   = (HMENU) HIWORD( lParam );
  486.      #endif
  487.  
  488.       if( (wmhMenu == 0) && (wmFlags = -1) ) {
  489.         tmp = idMenuSelect = 0;
  490.         SetWindowText(hWndMenuField, TEXT( "Ready..." ) );
  491.       }
  492.       else if(wmhMenu == 0) {
  493.         /* don't do anything for this */
  494.       } else if(wmFlags & MF_POPUP) {
  495.         if( (HMENU) wmMenuCmd == hSysMenuMain )
  496.           idMenuSelect = IDM_SYSMENU;
  497.         else if( (HMENU) wmMenuCmd == hFileMenu )
  498.           idMenuSelect = IDM_FILE;
  499.         else if( (HMENU) wmMenuCmd == hHelpMenu )
  500.           idMenuSelect = IDM_HELP;
  501.       }
  502.       else {
  503.         if(wmMenuCmd != 0) {         /* separators have wparam of 0 */
  504.           idMenuSelect = wmMenuCmd;
  505.         }
  506.       }
  507.  
  508.       if( idMenuSelect != tmp ) {
  509.         if( !LoadString( hInstance, (int) idMenuSelect, szMsg, sizeof(szMsg) ) ) {
  510.           if( idMenuSelect != (WORD) -1 ){
  511.             wsprintf( (LPTSTR) szMsg, TEXT( "Unable to load menu string #%u" ), idMenuSelect );
  512.           }
  513.           else {
  514.             lstrcpy(szMsg, TEXT( "Unsupported Function" ) );
  515.           }
  516.         }
  517.         SetWindowText( hWndMenuField, szMsg );
  518.       }
  519.       break;
  520.  
  521.     case WM_CLOSE: {
  522.       DestroyWindow( hWnd );
  523.       return( FALSE );
  524.     }
  525.  
  526.     case WM_DESTROY:       // message: window being destroyed
  527.       PostQuitMessage( 0 );
  528.       return( FALSE );
  529.  
  530.     default:              // Passes it on if unproccessed
  531.       return( DefFrameProc( hWnd, hWndMdiClient, uMsg, wParam, lParam ) );
  532.   }
  533.  
  534.   return( FALSE );
  535. }
  536.  
  537.  
  538. // **************************************************************************
  539. // FUNCTION : MdiChildWndProc( HWND, UINT, WPARAM, LPARAM )
  540. // PURPOSE  : Processes messages for the MDI Child windows
  541. // MESSAGES :
  542. // **************************************************************************
  543. LRESULT CALLBACK
  544. MdiChildWndProc( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  545. {
  546.   switch( uMsg ) {
  547.  
  548.     case WM_CREATE: {
  549.       HWND hWndEdit;
  550.  
  551.       /* Create an edit control */
  552.       hWndEdit = CreateWindow( TEXT( "Edit" ), NULL,
  553.                    WS_CHILD | WS_MAXIMIZE | WS_VISIBLE |
  554.                    WS_HSCROLL | WS_VSCROLL | ES_AUTOHSCROLL | ES_AUTOVSCROLL |
  555.                    ES_MULTILINE,
  556.                    0, 0, 0, 0,
  557.                    hWnd,
  558.                    (HMENU) NULL,
  559.                    hInstance,
  560.                    NULL );
  561.  
  562.       SetFocus( hWndEdit );
  563.       break;
  564.     }
  565.  
  566.     case WM_CLOSE:
  567.       if( QueryCloseMdiChild( hWnd ) ) {
  568.         SendMessage( hWndMdiClient, WM_MDIDESTROY, (WPARAM) hWnd, 0L );
  569.         return DefMDIChildProc( hWnd, uMsg, wParam, lParam );
  570.       }
  571.       break;
  572.  
  573.     default:
  574.       return DefMDIChildProc( hWnd, uMsg, wParam, lParam );
  575.  
  576.   }
  577.  
  578.   return( FALSE );
  579. }
  580.  
  581.  
  582. // **************************************************************************
  583. // FUNCTION : AboutDlgProc( HWND, UINT, WPARAM, LPARAM )
  584. // PURPOSE  : Processes messages for "About" dialog box
  585. // MESSAGES :
  586. //   WM_INITDIALOG - initialize dialog box
  587. //   WM_COMMAND    - Input received
  588. //     IDOK        - OK button selected
  589. //     IDCANCEL    - Cancel button selected
  590. // COMMENTS:
  591. //   No initialization is needed for this particular dialog box.
  592. //   In this case, TRUE must be returned to Windows.
  593. //   Wait for user to click on "Ok" button, then close the dialog box.
  594. // **************************************************************************
  595. LRESULT CALLBACK
  596. AboutDlgProc( HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  597. {
  598.   UNREFERENCED_PARAMETER( lParam );
  599.  
  600.   switch( uMsg ) {
  601.  
  602.     case WM_COMMAND:
  603.       switch( wParam ) {
  604.  
  605.         case IDOK:
  606.           EndDialog( hDlg, TRUE );
  607.           return( TRUE );
  608.  
  609.         case IDCANCEL:
  610.           EndDialog( hDlg, FALSE );
  611.           return( FALSE );
  612.       }
  613.       break;
  614.  
  615.     case WM_INITDIALOG:
  616.       return( TRUE );
  617.  
  618.     case WM_CLOSE:
  619.       return( TRUE );
  620.  
  621.   }
  622.  
  623.   return( FALSE );
  624. }
  625.  
  626.  
  627. // ************************************************************************
  628. // FUNCTION : CreateMdiChildWindow( LPCTSTR )
  629. // PURPOSE  :
  630. // COMMENTS :
  631. // ************************************************************************
  632. HWND WINAPI
  633. CreateMdiChildWindow( LPCTSTR MdiChildName )
  634. {
  635.   HWND            hWndMdiChild;
  636.   MDICREATESTRUCT mcs;
  637.  
  638.   if( !MdiChildName )
  639.     mcs.szTitle = TEXT( "Untitled" );
  640.   else
  641.     mcs.szTitle = MdiChildName;
  642.  
  643.   mcs.szClass    = lpszMdiChildClassName;
  644.   mcs.hOwner     = hInstance;
  645.   mcs.x = mcs.cx = (UINT) CW_USEDEFAULT;  // Use the default size for the window
  646.   mcs.y = mcs.cy = (UINT) CW_USEDEFAULT;
  647.   mcs.style      = WS_CHILD | WS_CLIPSIBLINGS | WS_SYSMENU | WS_CAPTION |
  648.                    WS_THICKFRAME | WS_MAXIMIZEBOX | WS_MINIMIZEBOX;
  649.  
  650.   // tell the MDI Client to create the child
  651.   hWndMdiChild = (HWND) SendMessage ( hWndMdiClient, WM_MDICREATE, 0,
  652.                    (LPARAM) (LPMDICREATESTRUCT) &mcs );
  653.  
  654.   return( hWndMdiChild );
  655. }
  656.  
  657. // ************************************************************************
  658. // FUNCTION : QueryCloseMdiChild( HWND )
  659. // PURPOSE  :
  660. // COMMENTS :
  661. // ************************************************************************
  662. BOOL WINAPI
  663. QueryCloseMdiChild( HWND hWndMdiChild )
  664. {
  665.   TCHAR Buffer[256] = TEXT( "" );
  666.  
  667.   GetWindowText( hWndMdiChild, (LPTSTR) &Buffer, 256 );
  668.   switch( MessageBox( hWndMain,
  669.             TEXT( "Save contents before closing this window?" ),
  670.             Buffer, MB_YESNOCANCEL | MB_ICONQUESTION ) ) {
  671.  
  672.     case IDYES:
  673.       // SaveFile();
  674.       return( TRUE );
  675.  
  676.     case IDNO:
  677.       return( TRUE );
  678.  
  679.     default:
  680.       return( FALSE );
  681.  
  682.   }
  683.  
  684.   return( FALSE );
  685. }
  686.  
  687.  
  688. // ************************************************************************
  689. // FUNCTION : CloseAllMdiChildren( VOID )
  690. // PURPOSE  :
  691. // COMMENTS :
  692. // ************************************************************************
  693. VOID WINAPI
  694. CloseAllMdiChildren( VOID )
  695. {
  696.   HWND hWndMdiChild;
  697.  
  698.   // hide the MDI client window to avoid multiple repaints
  699.   // ShowWindow( hWndMdiClient,SW_HIDE );
  700.  
  701.   // As long as the MDI client has a child, destroy it
  702.   while ( hWndMdiChild = GetWindow (hWndMdiClient, GW_CHILD) ) {
  703.  
  704.     // Skip the icon title windows
  705.     while( hWndMdiChild && GetWindow( hWndMdiChild, GW_OWNER ) )
  706.       hWndMdiChild = GetWindow( hWndMdiChild, GW_HWNDNEXT );
  707.     if( hWndMdiChild )
  708.       SendMessage( hWndMdiChild, WM_CLOSE, 0, 0L );
  709.       //QueryCloseMdiChild( hWndMdiChild );
  710.     else
  711.       break;
  712.  
  713.   }
  714.   // ShowWindow( hWndMdiClient, SW_SHOW );
  715. }
  716.  
  717.  
  718. // ************************************************************************
  719. // FUNCTION : ErrorMessageBox( LPCTSTR, LPCTSTR, LPCTSTR, INT )
  720. // PURPOSE  : Displays an error message box with GetLastError information
  721. //            and allows the user to terminate or continue the process.
  722. // COMMENTS :
  723. // ************************************************************************
  724. BOOL
  725. ErrorMessageBox( LPCTSTR lpszText, LPCTSTR lpszTitle, LPCTSTR lpszFile, INT Line )
  726. {
  727.   #define ERROR_BUFFER_SIZE 512
  728.  
  729.   static TCHAR Format[] =
  730.     TEXT( "%s\n\n"                                  )
  731.     TEXT( "--Error Information--\n\n"               )
  732.     TEXT( "File : %s\n"                             )
  733.     TEXT( "Line : %d\n"                             )
  734.     TEXT( "Error Number : %d\n"                     )
  735.    #ifdef WIN32
  736.     TEXT( "Error Message : %s\n"                    )
  737.    #endif
  738.     TEXT( "Press OK to terminate this application." );
  739.  
  740.   HLOCAL hMessageBoxBuffer;
  741.   LPVOID lpMessageBoxBuffer;
  742.  
  743.  #ifdef WIN32
  744.   LPVOID lpMessageBuffer;
  745.  #endif
  746.   DWORD  dwError;
  747.  
  748.   //-- perform a simple check on the needed buffer size
  749.   if( lstrlen(lpszText) > (ERROR_BUFFER_SIZE - lstrlen(Format)) )
  750.     return( FALSE );
  751.  
  752.   //-- allocate the message box buffer
  753.   hMessageBoxBuffer  = LocalAlloc( LMEM_FIXED, ERROR_BUFFER_SIZE );
  754.   lpMessageBoxBuffer = LocalLock( hMessageBoxBuffer );
  755.  
  756.  #ifdef WIN32
  757.   //-- get the sytem error message
  758.   FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
  759.     NULL, dwError = GetLastError(), LANG_USER_DEFAULT,
  760.     (LPTSTR) &lpMessageBuffer, 0, NULL );
  761.  #endif
  762.  
  763.   //-- format the error messge box string
  764.   wsprintf( lpMessageBoxBuffer, Format, lpszText, lpszFile, Line, dwError
  765.    #ifdef WIN32
  766.      , lpMessageBuffer
  767.    #endif
  768.      );
  769.  
  770.   // -- display the error and allow the user to terminate or continue
  771.   if( MessageBox( NULL, lpMessageBoxBuffer, lpszTitle, MB_OKCANCEL )  == IDOK )
  772.     ExitProcess( 0 );
  773.  
  774.   //-- free all buffers
  775.  #ifdef WIN32
  776.   LocalFree( (HLOCAL) lpMessageBuffer );
  777.  #endif
  778.   LocalFree( (HLOCAL) hMessageBoxBuffer );
  779.  
  780.   return( TRUE );
  781. }
  782.  
  783.  
  784. // *************************************************************************
  785. //  FUNCTION: FillFontNameComboBox( HWND, int )
  786. //  PURPOSE:  Fills a ComboBox
  787. //  COMMENTS: Returns TRUE
  788. // *************************************************************************
  789. BOOL
  790. FillFontNameComboBox (HWND hWnd, int focus)
  791. {
  792.   int index = 0;
  793.  
  794.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Courier" ) );
  795.   SendMessage( hWnd, CB_SETITEMDATA, index++, 1 );
  796.  
  797.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Helv" ) );
  798.   SendMessage( hWnd, CB_SETITEMDATA, index++, 2 );
  799.  
  800.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Tms Rmn" ) );
  801.   SendMessage( hWnd, CB_SETITEMDATA, index++, 3 );
  802.  
  803.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Modern" ) );
  804.   SendMessage( hWnd, CB_SETITEMDATA, index++, 4 );
  805.  
  806.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Roman" ) );
  807.   SendMessage( hWnd, CB_SETITEMDATA, index++, 5 );
  808.  
  809.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Script" ) );
  810.   SendMessage( hWnd, CB_SETITEMDATA, index++, 6 );
  811.  
  812.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Symbol" ) );
  813.   SendMessage( hWnd, CB_SETITEMDATA, index++, 7 );
  814.  
  815.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "Zaph Dingbats" ) );
  816.   SendMessage( hWnd, CB_SETITEMDATA, index++, 8 );
  817.  
  818.   SendMessage( hWnd, CB_SETCURSEL, focus, 0 );
  819.  
  820.   return( TRUE );
  821. }
  822.  
  823.  
  824. // *************************************************************************
  825. //  FUNCTION: FillFontSizeComboBox( HWND, int )
  826. //  PURPOSE:  Fills a ComboBox
  827. //  COMMENTS: Returns TRUE
  828. // *************************************************************************
  829. BOOL
  830. FillFontSizeComboBox (HWND hWnd, int focus)
  831. {
  832.   int index = 0;
  833.  
  834.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "6" ) );
  835.   SendMessage( hWnd, CB_SETITEMDATA, index++, 6 );
  836.  
  837.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "8" ) );
  838.   SendMessage( hWnd, CB_SETITEMDATA, index++, 8 );
  839.  
  840.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "10" ) );
  841.   SendMessage( hWnd, CB_SETITEMDATA, index++, 10 );
  842.  
  843.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "12" ) );
  844.   SendMessage( hWnd, CB_SETITEMDATA, index++, 12 );
  845.  
  846.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "14" ) );
  847.   SendMessage( hWnd, CB_SETITEMDATA, index++, 14 );
  848.  
  849.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "16" ) );
  850.   SendMessage( hWnd, CB_SETITEMDATA, index++, 16 );
  851.  
  852.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "18" ) );
  853.   SendMessage( hWnd, CB_SETITEMDATA, index++, 18 );
  854.  
  855.   SendMessage( hWnd, CB_ADDSTRING, 0, (LPARAM) TEXT( "24" ) );
  856.   SendMessage( hWnd, CB_SETITEMDATA, index++, 24 );
  857.  
  858.   SendMessage( hWnd, CB_SETCURSEL, focus, 0 );
  859.  
  860.   return( TRUE );
  861. }
  862.